//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __EVENTQUEUE_H__
#define __EVENTQUEUE_H__

#include <driver.h>
#include <linknode.h>
#include "drv_queue.h"

#define HOST_KEYBOARD 0
#define HOST_MOUSE    1
#define HOST_NUMBER   2

class CEventQueue : public CDeviceDriver, public DLinkNode
{
public:
    CARAPI Read(
        /* [in] */  Int64 offset,
        /* [in] */  Int32 numberOfBytesToRead,
        /* [out] */ MemoryBuf * pData,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */  Int64 offset,
        /* [in] */ const  MemoryBuf & ebbData,
        /* [out] */ Int32 * pNumberOfBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */  Handle32 constrolCode,
        /* [in] */ const  MemoryBuf & ebbInData,
        /* [out] */ MemoryBuf * pOutData,
        /* [out] */ IEvent * * ppCompletionEvent);

    void Dispose();

public:
    CEventQueue(
            Int32 environmentId,
            Int32 size = 4,
            Int32 length = 32)
          : m_environmentId(environmentId),
            m_queue(size, length),
            m_hEvent(NULL) {}
    ~CEventQueue();

    ECode   Initialize();

public:
    Int32 m_environmentId;
private:
    Queue m_queue;
    PVoid m_hEvent;
};

// API for event Queue to create or destroy;
class CEventQueueSink
{
public:
    ECode CreateQueue(
        /* [in] */ Int32 environmentId,
        /* [in] */ Int32 hostType,
        /* [in] */ Int32 elementSize,
        /* [in] */ Int32 queueSize,
        /* [out] */ CEventQueue ** ppQueue);

    CEventQueue * GetQueue(
        /* [in] */ Int32 environmentId,
        /* [in] */ Int32 hostType);

public:
    CEventQueueSink();
    ~CEventQueueSink(){}

private:
    //RTL_CRITICAL_SECTION m_hLock;
    DLinkNode m_queueList[HOST_NUMBER];
};

EXTERN CEventQueueSink * GetEventQueueSink();

#endif //__EVENTQUEUE_H__

